package cn.myjerry.others.commons;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections4.Closure;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.functors.ChainedClosure;
import org.apache.commons.collections4.functors.IfClosure;
import org.apache.commons.collections4.functors.WhileClosure;

/**
 * 函数式编程 Closure 闭包 封装特定的业务功能
 * CollectionUtils.forAllDo(容器,功能类对象);
 * 1、Closure CollectionUtils.forAllDo(容器，功能类)
 * 2、IfClosure IfClosure.ifClosure(断言,功能1,功能2)
 * 3、WhileClosure WhileClosure.whileClosure(断言,功能,标识)
 * 4、ChainedClosure.chainedClosure(功能列表);
 * @author Jerry
 *
 */
public class Demo03 {
	public static void main(String[] args) {
		//basic();
		//ifClosure();
		//whileClosure();
		chainClosure();
	}
	/**
	 * 折上减   先打折商品，进行9折，满百再减20
	 */
	public static void chainClosure() {
		List<Goods> goodsList = new ArrayList<>();
		goodsList.add(new Goods("A", 1100, true));
		goodsList.add(new Goods("B", 150, false));
		goodsList.add(new Goods("C", 130, false));
		goodsList.add(new Goods("D", 500, true));
		// 满百减20
		Closure<Goods> subtract = new Closure<Goods>() {
			@Override
			public void execute(Goods input) {
				if(input.getPrice() > 100) {
					input.setPrice(input.getPrice() - 20);
				}
			}
		};
		// 打折
		Closure<Goods> discount = new Closure<Goods>() {
			@Override
			public void execute(Goods input) {
				if(input.isDiscount()) {
					input.setPrice(input.getPrice() * 0.9);
				}
			}
		};
		// 二选一
		Closure<Goods> chainClo = ChainedClosure.chainedClosure(discount, subtract);
		// 关联
		CollectionUtils.forAllDo(goodsList, chainClo);
		Iterator<Goods> goodsIt = goodsList.iterator();
		while (goodsIt.hasNext()) {
			System.out.println(goodsIt.next());
		}
		
	}
	/**
	 * 确保所有的员工工资都大于10000,如果已经超过的不再上涨
	 */
	public static void whileClosure() {
		List<Employee> empList = new ArrayList<>();
		empList.add(new Employee("A", 8000));
		empList.add(new Employee("B", 9800));
		empList.add(new Employee("C", 8800));
		// 业务功能 每次上涨0.2
		Closure<Employee> cols = new Closure<Employee>() {
			@Override
			public void execute(Employee input) {
				input.setSalary(input.getSalary() * 1.2);
			}
		};
		// 判断
		Predicate<Employee> empPre = new Predicate<Employee>() {
			@Override
			public boolean evaluate(Employee object) {
				return object.getSalary() < 10000;
			}
		};
		// false 表示 while结构 先判断后执行   true do..while 先执行后判断
		Closure<Employee> whileCols = WhileClosure.whileClosure(empPre, cols, false);
		// 工具类
		CollectionUtils.forAllDo(empList, whileCols);
		Iterator<Employee> empIt = empList.iterator();
		while(empIt.hasNext()) {
			System.out.println(empIt.next());
		}
	}
	/**
	 * 二选一  如果是打折商品，进行9折，否则满百减20
	 */
	public static void ifClosure() {
		List<Goods> goodsList = new ArrayList<>();
		goodsList.add(new Goods("A", 1100, true));
		goodsList.add(new Goods("B", 150, false));
		goodsList.add(new Goods("C", 130, false));
		goodsList.add(new Goods("D", 500, true));
		/**
		 * 满百减20
		 */
		Closure<Goods> subtract = new Closure<Goods>() {
			@Override
			public void execute(Goods input) {
				if(input.getPrice() > 100) {
					input.setPrice(input.getPrice() - 20);
				}
			}
		};
		/**
		 * 打折
		 */
		Closure<Goods> discount = new Closure<Goods>() {
			@Override
			public void execute(Goods input) {
				if(input.isDiscount()) {
					System.out.println(input.toString());
					input.setPrice(input.getPrice() * 0.9);
				}
			}
		};
		// 判断
		Predicate<Goods> pres = new Predicate<Goods>() {
			@Override
			public boolean evaluate(Goods object) {
				return object.isDiscount();
			}
		};
		// 二选一
		Closure<Goods> ifClo = IfClosure.ifClosure(pres, discount, subtract);
		// 关联
		CollectionUtils.forAllDo(goodsList, ifClo);
		Iterator<Goods> goodsIt = goodsList.iterator();
		while (goodsIt.hasNext()) {
			System.out.println(goodsIt.next());
		}
	}
	/**
	 * 基本操作
	 */
	public static void basic() {
		// 数据
		List<Employee> empList = new ArrayList<>();
		empList.add(new Employee("A", 1000));
		empList.add(new Employee("B", 1500));
		empList.add(new Employee("C", 1300));
		empList.add(new Employee("D", 800));
		// 业务功能
		Closure<Employee> cols = new Closure<Employee>() {
			@Override
			public void execute(Employee input) {
				input.setSalary(input.getSalary() * 1.2);
			}
		};
		@SuppressWarnings("deprecation")
		Closure<Employee> forAllDo = CollectionUtils.forAllDo(empList, cols);
		Iterator<Employee> empIt = empList.iterator();
		while (empIt.hasNext()) {
			System.out.println(empIt.next());
		}
	}
}
